import problem as problem_core
from problem import ProblemAction
from Quoridor_game import GetNextLocation, WHITE

class QuoridorSearchState(problem_core.ProblemState):
    
    def __init__(self, qstate, x, y, player):
        self.map = map
        self.qstate = qstate
        self.x = x
        self.y = y
        self.player = player
        
    def getNexts(self):
        results = []
        if self.player == WHITE:
            directions = ['S', 'E', 'W', 'N']
        else:
            directions = ['N', 'E', 'W', 'S']
             
        for direction in directions:
            nextLoc = GetNextLocation((self.x,self.y), direction)
            nextRow = nextLoc[0]
            nextCol = nextLoc[1]   
            
            #moves out of board
            if nextRow < 0 or nextRow >= self.qstate.brdSize or nextCol < 0 or nextCol >= self.qstate.brdSize:
                continue
            #move illegal because of wall
            if not self._moveOkByWalls(direction, nextRow, nextCol):
                continue
            results.append(nextLoc)
        return results
    
    # checks if a move is not blocked by any wall
    def _moveOkByWalls(self, direction, nextRow, nextCol):
        if (direction == 'N'):
            if self.qstate.wallsH[nextRow][nextCol] == 1:
                return False
        elif (direction == 'S'):
            if self.qstate.wallsH[nextRow-1][nextCol] == 1:
                return False
        elif (direction == 'W'):
            if self.qstate.wallsV[nextCol][nextRow] == 1:
                return False
        elif (direction == 'E'):
            if self.qstate.wallsV[nextCol-1][nextRow] == 1:
                return False
        return True

    def getSuccessors(self):
        '''
        Generates all the actions that can be performed from this state, and
        the States those actions will create.
        
        @return: A dictionary containing each action as a key, and its state.
        '''
        
        
        res = dict()
        for tx, ty in self.getNexts():
            res[ProblemAction((self.x,self.y),(tx,ty))] = QuoridorSearchState(self.qstate, tx, ty, self.player)
        return res

    
    def isGoal(self):
        '''
        @return: Whether this Problem state is the searched goal or not.
        '''
        if (self.player == WHITE):
            return self.x == self.qstate.brdSize - 1 
        else:
            return self.x == 0 
    
    def __cmp__(self, other):
        '''
        The comparison method must be implemented to ensure deterministic results.
        @return: Negative if self < other, zero if self == other and strictly 
        positive if self > other.
        '''
        return cmp((self.x,self.y),(other.x,other.y))
    
    def __hash__(self):
        '''
        The hash method must be implemented for states to be inserted into sets 
        and dictionaries.
        @return: The hash value of the state.
        '''
        return hash((self.x, self.y))
    
    def __str__(self):
        return 'Location: (' + self.x + ',' + self.y + ')'
    
    def __repr__(self):
        return self.__str__()

